<?php

final class REST {
	private $AccountSid;
	private $AccountToken;
	private $AppId;
	private $ServerIP;
	private $ServerPort;
	private $SoftVersion;
	private $Batch;  //时间戳
	private $BodyType = "xml";//包体格式，可填值：json 、xml
	private $enabeLog = true; //日志开关。可填值：true、
	private $Filename="./sms_log.txt"; //日志文件
	private $Handle;
	function __construct($ServerIP,$ServerPort,$SoftVersion)
	{
		$this->Batch = date("YmdHis");
		$this->ServerIP = $ServerIP;
		$this->ServerPort = $ServerPort;
		$this->SoftVersion = $SoftVersion;
		$this->Handle = fopen($this->Filename, 'a');
	}

	/**
	 * 设置主帐号
	 *
	 * @param AccountSid 主帐号
	 * @param AccountToken 主帐号Token
	 */
	function setAccount($AccountSid,$AccountToken){
		$this->AccountSid = $AccountSid;
		$this->AccountToken = $AccountToken;
	}


	/**
	 * 设置应用ID
	 *
	 * @param AppId 应用ID
	 */
	function setAppId($AppId){
		$this->AppId = $AppId;
	}

	/**
	 * 打印日志
	 *
	 * @param log 日志内容
	 */
	function showlog($log){
		if($this->enabeLog){
			fwrite($this->Handle,$log."\n");
		}
	}

	/**
	 * 发起HTTPS请求
	 */
	function curl_post($url,$data,$header,$post=1)
	{
		//初始化curl
		$ch = curl_init();
		//参数设置
		$res= curl_setopt ($ch, CURLOPT_URL,$url);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
		curl_setopt ($ch, CURLOPT_HEADER, 0);
		curl_setopt($ch, CURLOPT_POST, $post);
		if($post)
			curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
		curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch,CURLOPT_HTTPHEADER,$header);
		$result = curl_exec ($ch);
		//连接失败
		if($result == FALSE){
			if($this->BodyType=='json'){
				$result = "{\"statusCode\":\"172001\",\"statusMsg\":\"网络错误\"}";
			} else {
				$result = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Response><statusCode>172001</statusCode><statusMsg>网络错误</statusMsg></Response>";
			}
		}

		curl_close($ch);
		return $result;
	}

	 

	/**
	 * 发送模板短信
	 * @param to 短信接收彿手机号码集合,用英文逗号分开
	 * @param datas 内容数据
	 * @param $tempId 模板Id
	 */
	function sendTemplateSMS($to,$datas,$tempId)
	{
		//主帐号鉴权信息验证，对必选参数进行判空。
		$auth=$this->accAuth();
		if($auth!=""){
			return $auth;
		}
		// 拼接请求包体
		if($this->BodyType=="json"){
			$data="";
			for($i=0;$i<count($datas);$i++){
				$data = $data. "'".$datas[$i]."',";
			}
			$body= "{'to':'$to','templateId':'$tempId','appId':'$this->AppId','datas':[".$data."]}";
		}else{
			$data="";
			for($i=0;$i<count($datas);$i++){
				$data = $data. "<data>".$datas[$i]."</data>";
			}
			$body="<TemplateSMS>
			<to>$to</to>
			<appId>$this->AppId</appId>
			<templateId>$tempId</templateId>
			<datas>".$data."</datas>
			</TemplateSMS>";
        }
        $this->showlog("request body = ".$body);
        // 大写的sig参数
        		$sig =  strtoupper(md5($this->AccountSid . $this->AccountToken . $this->Batch));
        		// 生成请求URL
        		$url="https://$this->ServerIP:$this->ServerPort/$this->SoftVersion/Accounts/$this->AccountSid/SMS/TemplateSMS?sig=$sig";
        		$this->showlog("request url = ".$url);
        		// 生成授权：主帐户Id + 英文冒号 + 时间戳。
        		$authen = base64_encode($this->AccountSid . ":" . $this->Batch);
        		// 生成包头
        		$header = array("Accept:application/$this->BodyType","Content-Type:application/$this->BodyType;charset=utf-8","Authorization:$authen");
        		// 发送请求
        		$result = $this->curl_post($url,$body,$header);
        		$this->showlog("response body = ".$result);
        if($this->BodyType=="json"){//JSON格式
        $datas=json_decode($result);
        		}else{ //xml格式
        		$datas = simplexml_load_string(trim($result," \t\n\r"));
        		}
        				//  if($datas == FALSE){
        				//            $datas = new stdClass();
        				//            $datas->statusCode = '172003';
        				//            $datas->statusMsg = '返回包体错误';
        				//        }
        				//重新装填数据
        					if($datas->statusCode==0){
        						if($this->BodyType=="json"){
        						$datas->TemplateSMS =$datas->templateSMS;
        						unset($datas->templateSMS);
        				}
	}

	return $datas;
	 }
	  
	/**
	* 主帐号鉴权
	*/
	function accAuth()
	{
	if($this->ServerIP==""){
		$data = new stdClass();
		$data->statusCode = '172004';
		$data->statusMsg = 'IP为空';
		return $data;
	}
		if($this->ServerPort<=0){
		$data = new stdClass();
		$data->statusCode = '172005';
		$data->statusMsg = '端口错误（小于等于0）';
		return $data;
		}
				if($this->SoftVersion==""){
				$data = new stdClass();
				$data->statusCode = '172013';
				$data->statusMsg = '版本号为空';
					return $data;
				}
				if($this->AccountSid==""){
				$data = new stdClass();
				$data->statusCode = '172006';
				$data->statusMsg = '主帐号为空';
				return $data;
	}
	if($this->AccountToken==""){
	$data = new stdClass();
	$data->statusCode = '172007';
	$data->statusMsg = '主帐号令牌为空';
	return $data;
	}
	if($this->AppId==""){
	$data = new stdClass();
	$data->statusCode = '172012';
	$data->statusMsg = '应用ID为空';
	return $data;
	}
	}
}

final class sms {
	public $topdomain;
	public $key;
	public $smsapi_url;
	private $userid;
	private $password;
	
	//主帐号,对应开官网发者主账号下的 ACCOUNT SID
	private $accountSid= '8a216da85624dadc0156262d7fb702e5';
	//主帐号令牌,对应官网开发者主账号下的 AUTH TOKEN
	private $accountToken= '7d6556e8f2934b209e3850c8a378fd08';
	//应用Id，在官网应用列表中点击应用，对应应用详情中的APP ID
	//在开发调试的时候，可以使用官网自动为您分配的测试Demo的APP ID
	private $appId='8a216da85624dadc0156262d805202eb';
	//请求地址
	//沙盒环境（用于应用开发调试）：sandboxapp.cloopen.com
	//生产环境（用户应用上线使用）：app.cloopen.com
	private $serverIP='app.cloopen.com';
	//请求端口，生产环境和沙盒环境一致
	private $serverPort='8883';
	//REST版本号，在官网文档REST介绍中获得。
	private $softVersion='2013-12-26';
	
	/**
	 * 
	 * 初始化接口类
	 * @param int $userid 用户id
	 * @param int $productid 产品id
	 * @param string $sms_key 密钥
	 */
	public function __construct($userid='',$password='') {
		if (!empty($userid) && !empty($password)){
			$this->userid = $userid;
			$this->password = $password;
		}else{
			$config = require_once APP_INC_PATH.'/config/mobile.inc.php';
			$account = $config['cfg_mobile_0'];
			if (empty($config) || empty($account)){
				return array('status' => 0,'msg' => "短信功能未开启");
			}
			//$this->userid = $account['mid'];
			//$this->password = $account['mpass'];
			$this->accountSid = $account['accountsid'];
			$this->accountToken = $account['authtoken'];
			$this->appId = $account['appid'];
		}	
	}
	
	public function checkmobile($mobilephone) {
		$mobilephone = trim($mobilephone);
		if(_checkmobile($mobilephone)){
			return  $mobilephone;
		} else {
			return false;
		}
	}
	
	

	/**
	 * 发送模板短信
	 * @param to 手机号码集合,用英文逗号分开
	 * @param datas 内容数据 格式为数组 例如：array('Marry','Alon')，如不需替换请填 null
	 * @param $tempId 模板Id,测试应用和未上线应用使用测试模板请填写1，正式应用上线后填写已申请审核通过的模板ID
	 */
	public function sendTemplateSMS($to,$datas,$tempId){
		//初始化REST SDK
		$rest = new REST($this->serverIP,$this->serverPort,$this->softVersion);
		$rest->setAccount($this->accountSid,$this->accountToken);
		$rest->setAppId($this->appId);
		// 发送模板短信
		//echo "Sending TemplateSMS to $to <br/>";
		$result = $rest->sendTemplateSMS($to,$datas,$tempId);
		if($result == NULL ) {
			return false;
			echo "result error!";
			break;
	     }
	     if($result->statusCode!=0) {
	     	//return false;
	     	if ($result->statusCode==160038){
	     		return array('status' => 0,'msg' => '短信验证码发送过频繁');
	     	}else{
	     		return false;
	     	}
	     	echo "error code :" . $result->statusCode . "<br>";
	     	echo "error msg :" . $result->statusMsg . "<br>";
	     		//TODO 添加错误处理逻辑
	     }else{
	     	
	     	return true;
	     	
	     	echo "Sendind TemplateSMS success!<br/>";
	     	// 获取返回信息
         	$smsmessage = $result->TemplateSMS;
	     	echo "dateCreated:".$smsmessage->dateCreated."<br/>";
         	echo "smsMessageSid:".$smsmessage->smsMessageSid."<br/>";
         	//TODO 添加成功处理逻辑
	     }
	 }
	
	
	/**
	 * 
	 * 批量发送短信
	 * @param array $mobile 手机号码
	 * @param string $content 短信内容
	 * @param datetime $send_time 发送时间
	 * @param string $charset 短信字符类型 gbk / utf-8
	 * @param string $id_code 唯一值 、可用于验证码
	 */
	public function sendSms($content='',$mobile='', $send_time='', $charset='utf-8',$id_code = '') {
		$content = Sms::_safe_replace($content);
		$content = urlencode($content);
		$data = array(
			'UserName' => $this->userid,
			'UserPass' => $this->password,			
			'Text' => $content,
			'Mobile'=>$mobile,
			);
			$post = '';
			foreach($data as $k=>$v) {
				$post .= '&'.$k.'='.$v;
			}
			
			$smsapi_senturl = 'http://www.exincn.com/sms/api/index.asp?Action=send&SmsFlag=0';
			//$smsapi_senturl  = "";
			$return = Sms::_post($smsapi_senturl, 0, $post);
			$this->statuscode = $return;
			//end
			
			return $this->statuscode;
			
			/*
			$this->statuscode = 0;
			return $this->statuscode;
		}*/
	}
		
	
	
	/**
	 *  post数据
	 *  @param string $url		post的url
	 *  @param int $limit		返回的数据的长度
	 *  @param string $post		post数据，字符串形式username='dalarge'&password='123456'
	 *  @param string $cookie	模拟 cookie，字符串形式username='dalarge'&password='123456'
	 *  @param string $ip		ip地址
	 *  @param int $timeout		连接超时时间
	 *  @param bool $block		是否为阻塞模式
	 *  @return string			返回字符串
	 */
	
	private function _post($url, $limit = 0, $post = '', $cookie = '', $ip = '', $timeout = 15, $block = true) {
		$return = '';
		$url=str_replace('&amp;','&',$url);
		
		$matches = parse_url($url);
		
		$host = $matches['host'];
		$path = $matches['path'] ? $matches['path'].($matches['query'] ? '?'.$matches['query'] : '') : '/';
		
		$post=substr($post,1,strlen($post));
		$port = !empty($matches['port']) ? $matches['port'] : 80;
		
		$siteurl = Sms::_get_url();
		
		if($post) {
			$out = "POST $path HTTP/1.1\r\n";
			$out .= "Accept: */*\r\n";
			$out .= "Referer: ".$siteurl."\r\n";
			$out .= "Accept-Language: zh-cn\r\n";
			$out .= "Content-Type: application/x-www-form-urlencoded\r\n";
			$out .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
			$out .= "Host: $host\r\n" ;
			$out .= 'Content-Length: '.strlen($post)."\r\n" ;
			$out .= "Connection: Close\r\n" ;
			$out .= "Cache-Control: no-cache\r\n" ;
			$out .= "Cookie: $cookie\r\n\r\n" ;
			$out .= $post ;
		} else {
			$out = "GET $path HTTP/1.1\r\n";
			$out .= "Accept: */*\r\n";
			$out .= "Referer: ".$siteurl."\r\n";
			$out .= "Accept-Language: zh-cn\r\n";
			$out .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
			$out .= "Host: $host\r\n";
			$out .= "Connection: Close\r\n";
			$out .= "Cookie: $cookie\r\n\r\n";
		}
		$fp = @fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
		if(!$fp) return '';
		
		stream_set_blocking($fp, $block);
		stream_set_timeout($fp, $timeout);
		
		@fwrite($fp, $out);
		$status = stream_get_meta_data($fp);
	
		if($status['timed_out']) return '';	
		while (!feof($fp)) {
			if(($header = @fgets($fp)) && ($header == "\r\n" ||  $header == "\n"))  break;				
		}
		
		$stop = false;
		while(!feof($fp) && !$stop) {
			$data = fread($fp, ($limit == 0 || $limit > 8192 ? 8192 : $limit));
			$return .= $data;
			if($limit) {
				$limit -= strlen($data);
				$stop = $limit <= 0;
			}
		}
		@fclose($fp);
		//部分虚拟主机返回数值有误，暂不确定原因，过滤返回数据格式
		$return_arr = explode("\n", $return);
		if(isset($return_arr[1])) {
			$return = trim($return_arr[1]);
		}
		unset($return_arr);
		
		return $return;
	}

	/**
	 * 获取当前页面完整URL地址
	 */
	private function _get_url() {
		$sys_protocal = isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443' ? 'https://' : 'http://';
		$php_self = $_SERVER['PHP_SELF'] ? Sms::_safe_replace($_SERVER['PHP_SELF']) : Sms::_safe_replace($_SERVER['SCRIPT_NAME']);
		$path_info = isset($_SERVER['PATH_INFO']) ? Sms::_safe_replace($_SERVER['PATH_INFO']) : '';
		$relate_url = isset($_SERVER['REQUEST_URI']) ? Sms::_safe_replace($_SERVER['REQUEST_URI']) : $php_self.(isset($_SERVER['QUERY_STRING']) ? '?'.Sms::_safe_replace($_SERVER['QUERY_STRING']) : $path_info);
		return $sys_protocal.(isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '').$relate_url;
	}
	
	/**
	 * 安全过滤函数
	 *
	 * @param $string
	 * @return string
	 */
	private function _safe_replace($string) {
		$string = str_replace('%20','',$string);
		$string = str_replace('%27','',$string);
		$string = str_replace('%2527','',$string);
		$string = str_replace('*','',$string);
		$string = str_replace('"','&quot;',$string);
		$string = str_replace("'",'',$string);
		$string = str_replace('"','',$string);
		$string = str_replace(';','',$string);
		$string = str_replace('<','&lt;',$string);
		$string = str_replace('>','&gt;',$string);
		$string = str_replace("{",'',$string);
		$string = str_replace('}','',$string);
		$string = str_replace('\\','',$string);
		return $string;
	}
}
?>